﻿using System;
using System.Configuration;
using System.IO;
using System.Net;
using System.Web.Mvc;
using NHibernate;
using NHibernate.Criterion;
using Web.Extensions;
using Web.HelperClasses.AvatarService;
using Web.Model;
using Web.OAuth;

namespace Web.Controllers
{
    public abstract class OAuthLoginController : Controller
    {
		protected abstract string TokenManagerKey { get; }
		protected abstract string CustomerKey { get; }
		protected abstract string CustomerSecret { get; }

		protected InMemoryTokenManager GetTokenManager()
		{
			var tokenManager = (InMemoryTokenManager)HttpContext.Application[TokenManagerKey];
			if (tokenManager == null)
			{
				string consumerKey = ConfigurationManager.AppSettings[CustomerKey];
				string consumerSecret = ConfigurationManager.AppSettings[CustomerSecret];
				if (!string.IsNullOrEmpty(consumerKey))
				{
					tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
					HttpContext.Application[TokenManagerKey] = tokenManager;
				}
			}

			return tokenManager;
		}

		[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Head)]
        public abstract ActionResult SendRequest(Uri callbackUri);

        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Head)]
        public abstract ActionResult Callback(Uri callbackUri);

    	protected void CreateOrAuthorizeUser(AccountInfo accountInfo)
    	{
			var user = session
				.CreateCriteria<User>()
				.Add(Restrictions.Eq("Email", accountInfo.Email))
				.UniqueResult<User>();

			if (user == null)
			{
				user = new User
				       	{
				       		DisplayName = accountInfo.Name,
				       		Password = null,
				       		Email = accountInfo.Email,
				       		HideEmail = true,
                            AccountSource = accountInfo.AccountSource
				       	};
				if (accountInfo.AccountSource != AccountSource.Vkontakte)
				{
					user.NotificationEmail = accountInfo.Email;
				}
				session.Save(user);
				
                Stream imageStream = accountInfo.GetAvatarInputStream();
                if (imageStream != null)
                {
                    avatarService.UploadNew(user.Id, imageStream);
                    imageStream.Close();
                }
                session.Transaction.Commit();
			}

			userSession.LogIn(user);
    	}

        public OAuthLoginController(ISession session, IUserSession userSession, AvatarService avatarService)
		{
			this.session = session;
			this.userSession = userSession;
            this.avatarService = avatarService;
		}

    	readonly ISession session;
		readonly IUserSession userSession;
        readonly AvatarService avatarService;
    }

	public class AccountInfo
	{
		public string Email { get; set; }
		public string Name { get; set; }
        public string Photo { get; set; }
        public AccountSource AccountSource { get; set; }

        public virtual Stream GetAvatarInputStream()
        {
            if (String.IsNullOrEmpty(Photo)) return null;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Photo);
            WebResponse response = request.GetResponse();
 
            return response.GetResponseStream();
        }
	}

	
}
